home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow_WinXP / VMR / Cube / app.cpp next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  26.0 KB  |  993 lines

  1. //------------------------------------------------------------------------------
  2. // File: app.cpp
  3. //
  4. // Desc: DirectShow sample code - VMR-based Cube video player
  5. //
  6. // Copyright (c) 1994 - 2001, Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9. #include <streams.h>
  10. #include <atlbase.h>
  11. #include <atlconv.cpp>
  12. #include <mmreg.h>
  13. #include <commctrl.h>
  14.  
  15. #include <initguid.h>
  16. #include "project.h"
  17. #include "resource.h"
  18.  
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21.  
  22.  
  23. /* -------------------------------------------------------------------------
  24. ** Global variables that are initialized at run time and then stay constant.
  25. ** -------------------------------------------------------------------------
  26. */
  27. HINSTANCE           hInst;
  28. HICON               hIconVideoCd;
  29. HWND                hwndApp;
  30. HWND                g_hwndToolbar;
  31. CMpegMovie          *pMpegMovie;
  32.  
  33. BOOL m_bFullScreen = FALSE;
  34.  
  35. /* -------------------------------------------------------------------------
  36. ** True Globals - these may change during execution of the program.
  37. ** -------------------------------------------------------------------------
  38. */
  39. DWORD g_State = VCD_NO_CD;
  40.  
  41. /* -------------------------------------------------------------------------
  42. ** Constants
  43. ** -------------------------------------------------------------------------
  44. */
  45. const TCHAR szClassName[] = TEXT("VMR_CubePlayer_CLASS");
  46. const TCHAR g_szNULL[]    = TEXT("\0");
  47. const TCHAR g_szEmpty[]   = TEXT("");
  48.  
  49. /*
  50. ** User interface values
  51. */
  52.       int   dyToolbar;
  53. const int   dxBitmap        = 16;
  54. const int   dyBitmap        = 15;
  55. const int   dxButtonSep     = 8;
  56. const TCHAR g_chNULL        = TEXT('\0');
  57. const LONG  g_Style         = WS_THICKFRAME | WS_POPUP | WS_CAPTION  |
  58.                               WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
  59.                               WS_CLIPCHILDREN;
  60.  
  61.  
  62. const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
  63.     { IDX_SEPARATOR,    1,                    0,               TBSTYLE_SEP           },
  64.     { IDX_1,            IDM_MOVIE_PLAY,       TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  65.     { IDX_2,            IDM_MOVIE_PAUSE,      TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  66.     { IDX_3,            IDM_MOVIE_STOP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  67.     { IDX_SEPARATOR,    1,                    0,               TBSTYLE_SEP           },
  68.     { IDX_4,            IDM_FULL_SCREEN,      TBSTATE_ENABLED, TBSTYLE_CHECK,  0, 0, 0, -1 }
  69. };
  70.  
  71.  
  72. /* -------------------------------------------------------------------------
  73. ** Local function prototypes
  74. ** -------------------------------------------------------------------------
  75. */
  76. void SetFullScreenMode(BOOL bMode);
  77. BOOL IsFullScreenMode();
  78. LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  79.  
  80.  
  81. /******************************Public*Routine******************************\
  82. * WinMain
  83. *
  84. *
  85. * Windows recognizes this function by name as the initial entry point
  86. * for the program.  This function calls the application initialization
  87. * routine, if no other instance of the program is running, and always
  88. * calls the instance initialization routine.  It then executes a message
  89. * retrieval and dispatch loop that is the top-level control structure
  90. * for the remainder of execution.  The loop is terminated when a WM_QUIT
  91. * message is received, at which time this function exits the application
  92. * instance by returning the value passed by PostQuitMessage().
  93. *
  94. * If this function must abort before entering the message loop, it
  95. * returns the conventional value NULL.
  96. *
  97. \**************************************************************************/
  98. int PASCAL
  99. WinMain(
  100.     HINSTANCE hInstance,
  101.     HINSTANCE hPrevInstance,
  102.     LPSTR lpCmdLineOld,
  103.     int nCmdShow
  104.     )
  105. {
  106.     USES_CONVERSION;
  107.  
  108.     HRESULT hres = CoInitialize(NULL);
  109.     if(hres == S_FALSE)
  110.     {
  111.         CoUninitialize();
  112.     }
  113.  
  114.     if(!hPrevInstance)
  115.     {
  116.         if(!InitApplication(hInstance))
  117.         {
  118.             return FALSE;
  119.         }
  120.     }
  121.  
  122.     /*
  123.     ** Perform initializations that apply to a specific instance
  124.     */
  125.     if(!InitInstance(hInstance, nCmdShow))
  126.     {
  127.         return FALSE;
  128.     }
  129.  
  130.     /* Verify that the VMR is present on this system */
  131.     if(!VerifyVMR())
  132.         return FALSE;
  133.  
  134.     /*
  135.     ** Acquire and dispatch messages until a WM_QUIT message is received.
  136.     */
  137.     int iRet = DoMainLoop();
  138.     QzUninitialize();
  139.     return iRet;
  140. }
  141.  
  142.  
  143. /*****************************Private*Routine******************************\
  144. * DoMainLoop
  145. *
  146. * Process the main message loop
  147. *
  148. \**************************************************************************/
  149. int
  150. DoMainLoop(
  151.     void
  152.     )
  153. {
  154.     MSG         msg;
  155.     HANDLE      ahObjects[8];;
  156.     int         cObjects;
  157.     HACCEL      haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
  158.  
  159.     //
  160.     // message loop lasts until we get a WM_QUIT message
  161.     //
  162.     for(;;)
  163.     {
  164.         if(pMpegMovie != NULL)
  165.         {
  166.             cObjects = 1;
  167.             ahObjects[0] = pMpegMovie->GetMovieEventHandle();
  168.         }
  169.         else
  170.         {
  171.             ahObjects[0] = NULL;
  172.             cObjects = 0;
  173.         }
  174.  
  175.         if(ahObjects[0] == NULL)
  176.         {
  177.             WaitMessage();
  178.         }
  179.         else
  180.         {
  181.             //
  182.             // wait for any message sent or posted to this queue
  183.             // or for a graph notification
  184.             //
  185.             DWORD result;
  186.  
  187.             result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
  188.                 INFINITE, QS_ALLINPUT);
  189.             if(result != (WAIT_OBJECT_0 + cObjects))
  190.             {
  191.                 VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
  192.                 continue;
  193.             }
  194.         }
  195.  
  196.         //
  197.         // When here, we either have a message or no event handle
  198.         // has been created yet.
  199.         //
  200.         // read all of the messages in this next loop
  201.         // removing each message as we read it
  202.         //
  203.         while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  204.         {
  205.             if(msg.message == WM_QUIT)
  206.             {
  207.                 return (int) msg.wParam;
  208.             }
  209.  
  210.             if(!TranslateAccelerator(hwndApp, haccel, &msg))
  211.             {
  212.                 TranslateMessage(&msg);
  213.                 DispatchMessage(&msg);
  214.             }
  215.         }
  216.     }
  217.  
  218. } // DoMainLoop
  219.  
  220.  
  221. /*****************************Private*Routine******************************\
  222. * InitApplication(HANDLE)
  223. *
  224. * This function is called at initialization time only if no other
  225. * instances of the application are running.  This function performs
  226. * initialization tasks that can be done once for any number of running
  227. * instances.
  228. *
  229. * In this case, we initialize a window class by filling out a data
  230. * structure of type WNDCLASS and calling the Windows RegisterClass()
  231. * function.  Since all instances of this application use the same window
  232. * class, we only need to do this when the first instance is initialized.
  233. *
  234. \**************************************************************************/
  235. BOOL
  236. InitApplication(
  237.     HINSTANCE hInstance
  238.     )
  239. {
  240.     WNDCLASS  wc;
  241.  
  242.     /*
  243.     ** Fill in window class structure with parameters that describe the
  244.     ** main window.
  245.     */
  246.     hIconVideoCd     = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON));
  247.  
  248.     wc.style         = CS_VREDRAW | CS_HREDRAW;
  249.     wc.lpfnWndProc   = VideoCdWndProc;
  250.     wc.cbClsExtra    = 0;
  251.     wc.cbWndExtra    = 0;
  252.     wc.hInstance     = hInstance;
  253.     wc.hIcon         = hIconVideoCd;
  254.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  255.     wc.hbrBackground = (HBRUSH)NULL;
  256.     wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU);
  257.     wc.lpszClassName = szClassName;
  258.  
  259.     /*
  260.     ** Register the window class and return success/failure code.
  261.     */
  262.     return RegisterClass(&wc);
  263. }
  264.  
  265.  
  266. /*****************************Private*Routine******************************\
  267. * InitInstance
  268. *
  269. * This function is called at initialization time for every instance of
  270. * this application.  This function performs initialization tasks that
  271. * cannot be shared by multiple instances.
  272. *
  273. * In this case, we save the instance handle in a static variable and
  274. * create and display the main program window.
  275. *
  276. \**************************************************************************/
  277. BOOL
  278. InitInstance(
  279.     HINSTANCE hInstance,
  280.     int nCmdShow
  281.     )
  282. {
  283.     HWND    hwnd;
  284.     RECT    rc;
  285.  
  286.     /*
  287.     ** Save the instance handle in static variable, which will be used
  288.     ** in many subsequent calls to Windows.
  289.     */
  290.     hInst = hInstance;
  291.     rc.left = rc.top = 100;
  292.     rc.bottom = rc.right = 400;
  293.  
  294.     /*
  295.     ** Create a main window for this application instance.
  296.     */
  297.     hwnd = CreateWindow(szClassName, IdStr(STR_APP_TITLE), g_Style,
  298.         rc.left, rc.top,
  299.         rc.right, rc.bottom,
  300.         NULL, NULL, hInstance, NULL);
  301.  
  302.     /*
  303.     ** If window could not be created, return "failure"
  304.     */
  305.     if(NULL == hwnd)
  306.     {
  307.         return FALSE;
  308.     }
  309.     hwndApp = hwnd;
  310.  
  311.     /*
  312.     ** Make the window visible; update its client area; and return "success"
  313.     */
  314.     SetPlayButtonsEnableState();
  315.     ShowWindow(hwnd, nCmdShow);
  316.     UpdateWindow(hwnd);
  317.  
  318.     return TRUE;
  319. }
  320.  
  321.  
  322. /*****************************Private*Routine******************************\
  323. * GetMoviePosition
  324. *
  325. * Place the movie in the centre of the client window.  
  326. * We do not stretch the the movie yet.
  327. *
  328. \**************************************************************************/
  329. void
  330. GetMoviePosition(
  331.     HWND hwnd,
  332.     long* xPos,
  333.     long* yPos,
  334.     long* pcx,
  335.     long* pcy
  336.     )
  337. {
  338.     RECT rc;
  339.  
  340.     GetAdjustedClientRect(&rc);
  341.  
  342.     *xPos = rc.left;
  343.     *yPos = rc.top;
  344.     *pcx = rc.right - rc.left;
  345.     *pcy = rc.bottom - rc.top;
  346. }
  347.  
  348.  
  349. /******************************Public*Routine******************************\
  350. * RepositionMovie
  351. *
  352. \**************************************************************************/
  353. void
  354. RepositionMovie(HWND hwnd)
  355. {
  356.     if(pMpegMovie)
  357.     {
  358.         long xPos, yPos, cx, cy;
  359.  
  360.         GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  361.  
  362.         pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
  363.         InvalidateRect(hwnd, NULL, false);
  364.         UpdateWindow(hwnd);
  365.     }
  366. }
  367.  
  368.  
  369. /*****************************Private*Routine******************************\
  370. * VideoCd_OnMove
  371. *
  372. \**************************************************************************/
  373. void
  374. VideoCd_OnMove(
  375.     HWND hwnd,
  376.     int x,
  377.     int y
  378.     )
  379. {
  380.     if(pMpegMovie)
  381.     {
  382.         if(pMpegMovie->GetStateMovie() != State_Running)
  383.         {
  384.             RepositionMovie(hwnd);
  385.         }
  386.         else
  387.         {
  388.             long xPos, yPos, cx, cy;
  389.  
  390.             // Reposition movie but don't invalidate the rect, since
  391.             // the next video frame will handle the redraw.
  392.             GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  393.             pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
  394.         }
  395.     }
  396. }
  397.  
  398.  
  399. /******************************Public*Routine******************************\
  400. * VideoCdWndProc
  401. *
  402. \**************************************************************************/
  403. LRESULT CALLBACK
  404. VideoCdWndProc(
  405.     HWND hwnd,
  406.     UINT message,
  407.     WPARAM wParam,
  408.     LPARAM lParam
  409.     )
  410. {
  411.     switch(message)
  412.     {
  413.         HANDLE_MSG(hwnd, WM_CREATE,            VideoCd_OnCreate);
  414.         HANDLE_MSG(hwnd, WM_PAINT,             VideoCd_OnPaint);
  415.         HANDLE_MSG(hwnd, WM_COMMAND,           VideoCd_OnCommand);
  416.         HANDLE_MSG(hwnd, WM_CLOSE,             VideoCd_OnClose);
  417.         HANDLE_MSG(hwnd, WM_DESTROY,           VideoCd_OnDestroy);
  418.         HANDLE_MSG(hwnd, WM_SIZE,              VideoCd_OnSize);
  419.         HANDLE_MSG(hwnd, WM_SYSCOLORCHANGE,    VideoCd_OnSysColorChange);
  420.         HANDLE_MSG(hwnd, WM_INITMENUPOPUP,     VideoCd_OnInitMenuPopup);
  421.         HANDLE_MSG(hwnd, WM_NOTIFY,            VideoCd_OnNotify);
  422.         HANDLE_MSG(hwnd, WM_KEYUP,             VideoCd_OnKeyUp);
  423.         HANDLE_MSG(hwnd, WM_MOVE,              VideoCd_OnMove);
  424.  
  425.         case WM_DISPLAYCHANGE:
  426.         {
  427.             if(pMpegMovie)
  428.             {
  429.                 pMpegMovie->DisplayModeChanged();
  430.             }
  431.         }
  432.         break;
  433.  
  434.         default:
  435.             return DefWindowProc(hwnd, message, wParam, lParam);
  436.     }
  437.  
  438.     return 0L;
  439. }
  440.  
  441.  
  442. /*****************************Private*Routine******************************\
  443. * VideoCd_OnCreate
  444. *
  445. \**************************************************************************/
  446. BOOL
  447. VideoCd_OnCreate(
  448.     HWND hwnd,
  449.     LPCREATESTRUCT lpCreateStruct
  450.     )
  451. {
  452.     InitCommonControls();
  453.  
  454.     /*
  455.     ** Create the toolbar and statusbar.
  456.     */
  457.     g_hwndToolbar = CreateToolbarEx(hwnd,
  458.                                     WS_VISIBLE | WS_CHILD |
  459.                                     TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
  460.                                     ID_TOOLBAR, NUMBER_OF_BITMAPS,
  461.                                     hInst, IDR_TOOLBAR, tbButtons,
  462.                                     DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
  463.                                     dxBitmap, dyBitmap, sizeof(TBBUTTON));
  464.  
  465.     if(g_hwndToolbar == NULL)
  466.     {
  467.         return FALSE;
  468.     }
  469.  
  470.     return TRUE;
  471. }
  472.  
  473. /*****************************Private*Routine******************************\
  474. * VideoCd_OnKeyUp
  475. *
  476. \**************************************************************************/
  477. void
  478. VideoCd_OnKeyUp(
  479.     HWND hwnd,
  480.     UINT vk,
  481.     BOOL fDown,
  482.     int cRepeat,
  483.     UINT flags
  484.     )
  485. {
  486.     // Catch escape sequences to stop fullscreen mode
  487.     if((vk == VK_ESCAPE) || (vk == VK_RETURN))
  488.     {
  489.         if(pMpegMovie && IsFullScreenMode())
  490.         {
  491.             SetFullScreenMode(FALSE);
  492.             SetPlayButtonsEnableState();
  493.         }
  494.     }
  495. }
  496.  
  497. /*****************************Private*Routine******************************\
  498. * VideoCd_OnPaint
  499. *
  500. \**************************************************************************/
  501. void
  502. VideoCd_OnPaint(
  503.     HWND hwnd
  504.     )
  505. {
  506.     PAINTSTRUCT ps;
  507.     HDC         hdc;
  508.     RECT        rc1;
  509.     RECT        rc2;
  510.  
  511.     /*
  512.     ** Draw a frame around the movie playback area.
  513.     */
  514.     GetClientRect(hwnd, &rc2);
  515.  
  516.     hdc = BeginPaint(hwnd, &ps);
  517.  
  518.     if(pMpegMovie)
  519.     {
  520.         long xPos, yPos, cx, cy;
  521.         GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  522.         SetRect(&rc1, xPos, yPos, xPos + cx, yPos + cy);
  523.  
  524.         HRGN rgnClient = CreateRectRgnIndirect(&rc2);
  525.         HRGN rgnVideo  = CreateRectRgnIndirect(&rc1);
  526.         CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
  527.  
  528.         HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
  529.         FillRgn(hdc, rgnClient, hbr);
  530.         DeleteObject(hbr);
  531.         DeleteObject(rgnClient);
  532.         DeleteObject(rgnVideo);
  533.  
  534.         pMpegMovie->RepaintVideo(hwnd, hdc);
  535.     }
  536.     else
  537.     {
  538.         FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
  539.     }
  540.  
  541.     EndPaint(hwnd, &ps);
  542. }
  543.  
  544.  
  545. /*****************************Private*Routine******************************\
  546. * AboutDlgProc
  547. *
  548. \**************************************************************************/
  549. LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  550. {
  551.     switch(message)
  552.     {
  553.         case WM_INITDIALOG:
  554.             return TRUE;
  555.  
  556.         case WM_COMMAND:
  557.             if(wParam == IDOK)
  558.             {
  559.                 EndDialog(hWnd, TRUE);
  560.                 return TRUE;
  561.             }
  562.             break;
  563.     }
  564.     return FALSE;
  565. }
  566.  
  567.  
  568. /*****************************Private*Routine******************************\
  569. * VideoCd_OnCommand
  570. *
  571. \**************************************************************************/
  572. void
  573. VideoCd_OnCommand(
  574.     HWND hwnd,
  575.     int id,
  576.     HWND hwndCtl,
  577.     UINT codeNotify
  578.     )
  579. {
  580.     switch(id)
  581.     {
  582.         case IDM_FILE_OPEN:
  583.             if(VcdPlayerOpenCmd())
  584.                 VcdPlayerPlayCmd();
  585.             break;
  586.  
  587.         case IDM_FILE_CLOSE:
  588.             VcdPlayerCloseCmd();
  589.             QzFreeUnusedLibraries();
  590.             break;
  591.  
  592.         case IDM_FILE_ABOUT:
  593.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX),
  594.                 hwnd,  (DLGPROC) AboutDlgProc);
  595.             break;
  596.  
  597.         case IDM_FILE_EXIT:
  598.             PostMessage(hwnd, WM_CLOSE, 0, 0L);
  599.             break;
  600.  
  601.         case IDM_MOVIE_PLAY:
  602.             VcdPlayerPlayCmd();
  603.             break;
  604.  
  605.         case IDM_MOVIE_STOP:
  606.             VcdPlayerStopCmd();
  607.             VcdPlayerRewindCmd();
  608.             break;
  609.  
  610.         case IDM_MOVIE_PAUSE:
  611.             VcdPlayerPauseCmd();
  612.             break;
  613.  
  614.         case IDM_FULL_SCREEN:
  615.             if(pMpegMovie)
  616.             {
  617.                 BOOL bFullScreen = (BOOL)SendMessage(g_hwndToolbar,
  618.                     TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0);
  619.                 SetFullScreenMode(bFullScreen);
  620.             }
  621.             break;
  622.     }
  623.  
  624.     SetPlayButtonsEnableState();
  625. }
  626.  
  627. /******************************Public*Routine******************************\
  628. * VideoCd_OnDestroy
  629. *
  630. \**************************************************************************/
  631. void
  632. VideoCd_OnDestroy(
  633.     HWND hwnd
  634.     )
  635. {
  636.     PostQuitMessage(0);
  637. }
  638.  
  639. /******************************Public*Routine******************************\
  640. * VideoCd_OnClose
  641. *
  642. \**************************************************************************/
  643. void
  644. VideoCd_OnClose(
  645.     HWND hwnd
  646.     )
  647. {
  648.     VcdPlayerCloseCmd();
  649.     DestroyWindow(hwnd);
  650. }
  651.  
  652. /******************************Public*Routine******************************\
  653. * VideoCd_OnSize
  654. *
  655. \**************************************************************************/
  656. void
  657. VideoCd_OnSize(
  658.     HWND hwnd,
  659.     UINT state,
  660.     int dx,
  661.     int dy
  662.     )
  663. {
  664.     if(IsWindow(g_hwndToolbar))
  665.         SendMessage(g_hwndToolbar, WM_SIZE, 0, 0L);
  666.  
  667.     RepositionMovie(hwnd);
  668. }
  669.  
  670.  
  671. /*****************************Private*Routine******************************\
  672. * VideoCd_OnSysColorChange
  673. *
  674. \**************************************************************************/
  675. void
  676. VideoCd_OnSysColorChange(
  677.     HWND hwnd
  678.     )
  679. {
  680.     FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
  681. }
  682.  
  683.  
  684. /*****************************Private*Routine******************************\
  685. * VideoCd_OnInitMenuPopup
  686. *
  687. \**************************************************************************/
  688. void
  689. VideoCd_OnInitMenuPopup(
  690.     HWND hwnd,
  691.     HMENU hMenu,
  692.     UINT item,
  693.     BOOL fSystemMenu
  694.     )
  695. {
  696.     UINT uFlags;
  697.  
  698.     if(item == 0)
  699.     { // File menu
  700.  
  701.         if(g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED))
  702.         {
  703.             uFlags = (MF_BYCOMMAND | MF_GRAYED);
  704.         }
  705.         else
  706.         {
  707.             uFlags = (MF_BYCOMMAND | MF_ENABLED);
  708.         }
  709.  
  710.         // Disable menu items until a movie is opened
  711.         EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags);
  712.         EnableMenuItem(hMenu, IDM_MOVIE_STOP, uFlags);
  713.         EnableMenuItem(hMenu, IDM_MOVIE_PLAY, uFlags);
  714.         EnableMenuItem(hMenu, IDM_MOVIE_PAUSE, uFlags);
  715.     }
  716. }
  717.  
  718.  
  719. /*****************************Private*Routine******************************\
  720. * VideoCd_OnGraphNotify
  721. *
  722. * This is where we get any notifications from the filter graph.
  723. *
  724. \**************************************************************************/
  725. void
  726. VideoCd_OnGraphNotify(
  727.     int stream
  728.     )
  729. {
  730.     long    lEventCode;
  731.  
  732.     lEventCode = pMpegMovie->GetMovieEventCode();
  733.  
  734.     switch(lEventCode)
  735.     {
  736.         case EC_FULLSCREEN_LOST:
  737.             SetPlayButtonsEnableState();
  738.             break;
  739.  
  740.         case EC_USERABORT:
  741.         case EC_ERRORABORT:
  742.             VcdPlayerStopCmd();
  743.             SetPlayButtonsEnableState();
  744.             break;
  745.  
  746.         case EC_COMPLETE:
  747.             VcdPlayerRewindCmd();
  748.             break;
  749.  
  750.         default:
  751.             break;
  752.     }
  753. }
  754.  
  755.  
  756. /*****************************Private*Routine******************************\
  757. * VideoCd_OnNotify
  758. *
  759. * This is where we get the text for tooltips
  760. *
  761. \**************************************************************************/
  762. LRESULT
  763. VideoCd_OnNotify(
  764.     HWND hwnd,
  765.     int idFrom,
  766.     NMHDR FAR* pnmhdr
  767.     )
  768. {
  769.     switch(pnmhdr->code)
  770.     {
  771.         case TTN_NEEDTEXT:
  772.             {
  773.                 LPTOOLTIPTEXT   lpTt;
  774.                 lpTt = (LPTOOLTIPTEXT)pnmhdr;
  775.  
  776.                 LoadString(hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
  777.                     sizeof(lpTt->szText));
  778.             }
  779.             break;
  780.     }
  781.  
  782.     return 0;
  783. }
  784.  
  785.  
  786. /******************************Public*Routine******************************\
  787. * SetPlayButtonsEnableState
  788. *
  789. * Sets the play buttons enable state to match the state of the current
  790. * cdrom device.  See below...
  791. *
  792. *
  793. *                 VCD Player buttons enable state table
  794. * --------------------------------------------------------------------
  795. * -E=Enabled D=Disabled      - Play - Pause - Eject - Stop  - Other -
  796. * --------------------------------------------------------------------
  797. * -Disk in use               -  D   -  D    -  D    -   D   -   D   -
  798. * --------------------------------------------------------------------
  799. * -No video cd or data cdrom -  D   -  D    -  E    -   D   -   D   -
  800. * --------------------------------------------------------------------
  801. * -Video cd (playing)        -  D   -  E    -  E    -   E   -   E   -
  802. * --------------------------------------------------------------------
  803. * -Video cd (paused)         -  E   -  D    -  E    -   E   -   E   -
  804. * --------------------------------------------------------------------
  805. * -Video cd (stopped)        -  E   -  D    -  E    -   D   -   E   -
  806. * --------------------------------------------------------------------
  807. *
  808. \**************************************************************************/
  809. void
  810. SetPlayButtonsEnableState(
  811.     void
  812.     )
  813. {
  814.     BOOL    fEnable, fPress;
  815.     BOOL    fVideoCdLoaded;
  816.  
  817.     /*
  818.     ** Do we have a video cd loaded.
  819.     */
  820.     if(g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE))
  821.     {
  822.         fVideoCdLoaded = FALSE;
  823.     }
  824.     else
  825.     {
  826.         fVideoCdLoaded = TRUE;
  827.     }
  828.  
  829.     /*
  830.     ** Do the play button
  831.     */
  832.     if(fVideoCdLoaded
  833.         && ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED)))
  834.     {
  835.         fEnable = TRUE;
  836.     }
  837.     else
  838.     {
  839.         fEnable = FALSE;
  840.     }
  841.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable);
  842.  
  843.     /*
  844.     ** Do the stop button
  845.     */
  846.     if(fVideoCdLoaded
  847.         && ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED)))
  848.     {
  849.         fEnable = TRUE;
  850.     }
  851.     else
  852.     {
  853.         fEnable = FALSE;
  854.     }
  855.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable);
  856.  
  857.     /*
  858.     ** Do the pause button
  859.     */
  860.     if(fVideoCdLoaded && (g_State & VCD_PLAYING))
  861.     {
  862.         fEnable = TRUE;
  863.     }
  864.     else
  865.     {
  866.         fEnable = FALSE;
  867.     }
  868.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable);
  869.  
  870.     /*
  871.     ** Do the remaining buttons
  872.     */
  873.     /*
  874.     ** Do the fullscreen button
  875.     */
  876.     fPress = (fVideoCdLoaded && IsFullScreenMode());
  877.  
  878.     SendMessage(g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0));
  879.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded && (g_State & VCD_PLAYING));
  880. }
  881.  
  882.  
  883. /*****************************Private*Routine******************************\
  884. * GetAdjustedClientRect
  885. *
  886. * Calculate the size of the client rect and then adjusts it to take into
  887. * account the space taken by the toolbar and status bar.
  888. *
  889. \**************************************************************************/
  890. void
  891. GetAdjustedClientRect(
  892.     RECT *prc
  893.     )
  894. {
  895.     RECT    rcTool;
  896.  
  897.     GetClientRect(hwndApp, prc);
  898.  
  899.     if(IsWindowVisible(g_hwndToolbar))
  900.     {
  901.         GetWindowRect(g_hwndToolbar, &rcTool);
  902.         prc->top += (rcTool.bottom - rcTool.top);
  903.     }
  904. }
  905.  
  906.  
  907. /******************************Public*Routine******************************\
  908. * IdStr
  909. *
  910. * Loads the given string resource ID into the passed storage.
  911. *
  912. \**************************************************************************/
  913. LPCTSTR
  914. IdStr(
  915.     int idResource
  916.     )
  917. {
  918.     static TCHAR    chBuffer[ STR_MAX_STRING_LEN ];
  919.  
  920.     if(LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0)
  921.     {
  922.         return g_szEmpty;
  923.     }
  924.  
  925.     return chBuffer;
  926. }
  927.  
  928.  
  929. /******************************Public*Routine******************************\
  930. * SetFullScreenMode
  931. *
  932. \**************************************************************************/
  933. void
  934. SetFullScreenMode(BOOL bMode)
  935. {
  936.     m_bFullScreen = bMode;
  937.  
  938.     // Defer until we activate the movie
  939.     if(pMpegMovie->GetStateMovie() != State_Running)
  940.     {
  941.         if(bMode == TRUE)
  942.             return;
  943.     }
  944.  
  945.     static HMENU hMenu;
  946.     static LONG  lStyle;
  947.     static int xs, ys, cxs, cys;
  948.  
  949.     HDC hdcScreen = GetDC(NULL);
  950.     int cx = GetDeviceCaps(hdcScreen,HORZRES);
  951.     int cy = GetDeviceCaps(hdcScreen,VERTRES);
  952.     ReleaseDC(NULL, hdcScreen);
  953.  
  954.     if(bMode)
  955.     {
  956.         hMenu = GetMenu(hwndApp);
  957.         lStyle = GetWindowStyle(hwndApp);
  958.  
  959.         WINDOWPLACEMENT wp;
  960.         wp.length = sizeof(WINDOWPLACEMENT);
  961.         GetWindowPlacement(hwndApp, &wp);
  962.         xs = wp.rcNormalPosition.left;
  963.         ys = wp.rcNormalPosition.top;
  964.         cxs = wp.rcNormalPosition.right - xs;
  965.         cys = wp.rcNormalPosition.bottom - ys;
  966.         ShowWindow(g_hwndToolbar, SW_HIDE);
  967.         SetMenu(hwndApp, NULL);
  968.         SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP | WS_VISIBLE);
  969.         SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
  970.         ShowCursor(FALSE);
  971.     }
  972.     else
  973.     {
  974.         ShowCursor(TRUE);
  975.         ShowWindow(g_hwndToolbar, SW_SHOW);
  976.         SetMenu(hwndApp, hMenu);
  977.         SetWindowLong(hwndApp, GWL_STYLE, lStyle);
  978.         SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
  979.     }
  980. }
  981.  
  982.  
  983. /******************************Public*Routine******************************\
  984. * IsFullScreenMode()
  985. *
  986. \**************************************************************************/
  987. BOOL
  988. IsFullScreenMode()
  989. {
  990.     return m_bFullScreen;
  991. }
  992.  
  993.